local skynet = require "skynet"
local Player = require"player"
local json = require "cjson"
local GameServer = require "poke"
local websocket = require"websocket"
local dump_T = require "dump_t"

--local GameHandler = require"poke_handler"

local pb = require "protobuf"
pb.register_file "./pbc/gctols.pb" 

local users = {}
local uid_pos = {}
local room_id

local game

local function send_msg(fd,msg)
	print("room send fd = " .. fd)
	websocket:send_binary(fd,msg)
end

local function talk(c,data)
	local pos = uid_pos[data.uid]
	if not pos then return end
	local isok = users[pos]:talk(data)
	if isok then
		for i = 1,3 do
			if i ~= pos and users[i] then
				users[i]:otherTalk(pos,data)
			end
		end
	else
		users[pos]:error(c,-1)
	end
end

local function prepare(data)
	if game then 
		print("game start already ")
		return 
	end
	local pos = uid_pos[data.uid]
	if not pos then return end
	local isok = users[pos]:myprepare(data)
	local prepare_count =  users[pos].prepare and 1 or 0
	if isok then
		for i = 1,3 do
			if i ~= pos and users[i] then
				users[i]:otherPrepare(pos,data)
				if users[i].prepare then
					prepare_count = prepare_count + 1
				end
			end
		end
		skynet.error("prepare count:",prepare_count)
		if prepare_count == 2 then 	--三个人都准备好了 开始游戏
			game = GameServer.new(users)
			game:start(room_id)
		end
	else
		users[pos]:error(c,-1)
	end
end

local function planemove(room_pos, position)
	if game then
		game:setPlayerPlanePos(room_pos, position)
	end
end

local function playerloadfinish(room_pos, data)
	if game then
		game:setPlayerReadyStates(room_pos, data)
	end
end

local function roomover()
	for i = 1,3 do
		if users[i] then
			users[i]:cancelprepare()
		end
	end
	game = null
end

local CMD = {}
function CMD.enter(user_info,con_info)
	local pos = false
	for i = 1,3 do
		if not users[i] then
			pos = i
			break
		end
	end
	local player
	if pos then
		player = Player.new(pos,user_info,con_info)
		local ret = {}
		for i = 1,3 do
			if users[i] then
				ret[#ret + 1] = users[i]:getInfo()
				users[i]:otherEnter(player:getInfo())
			end
		end
		uid_pos[con_info.uid] = pos
		users[pos] = player
		--skynet.call(con_info.gate,"lua","forward",con_info.fd)
		player:enter(room_id, ret, askid)
	end
	return pos
end

function CMD.relink(user_info,con_info)
	local pos = false
	if not game then 
		print("game not start")
		return pos
	end
	local player 
	local ret = {}
	for i = 1,3 do
		if users[i] then
			ret[#ret + 1] = users[i]:getInfo()
		end
	end
	for i = 1,3 do
		if users[i] then
			if users[i]:getInfo().uid == con_info.uid then
				pos = i
				player = users[i]
				player:relink(user_info,con_info)
				-- 玩家重连
				player:enter(room_id, ret, askid)
				game:relink(i, player)
				break
			end
		end
	end
	return pos
end

function CMD.start(roomid)
	room_id = roomid
end

function CMD.exit(room_pos, leavetype)
	if game and leavetype == 1 then
		-- 强制退出，假如已经开局，不能退出房间
		return false;
	end
	local uid = users[room_pos].uid
	local player_count = 0
	for i = 1,3 do
		if users[i] then
			users[i]:otherExit(room_pos,users[room_pos]:getInfo() )
			player_count = player_count + 1
		end
	end
	users[room_pos] = nil
	uid_pos[uid] = nil
	if player_count == 0 and game then
		game:exit()
		game = nil
	end
	return true;
end

function CMD.preare(data)
	prepare(data)
end

function CMD.planemove(room_pos, position)
	planemove(room_pos, position)
end

function CMD.playerloadfinish(room_pos, data)
	playerloadfinish(room_pos, data)
end

function CMD.roomover(room_pos)
	roomover(room_pos)
end

skynet.start(function()
	skynet.dispatch("lua",function(session,source,cmd,...)
		local f = assert(CMD[cmd])
		skynet.ret(skynet.pack(f(...)))
	end)
end)
